package com.tbl.modules.wms.controller.allo;

import com.alibaba.fastjson.JSON;
import com.google.common.collect.Maps;
import com.tbl.common.utils.DateUtils;
import com.tbl.common.utils.PageTbl;
import com.tbl.common.utils.PageUtils;
import com.tbl.common.utils.StringUtils;
import com.tbl.modules.platform.controller.AbstractController;
import com.tbl.modules.platform.util.DeriveExcel;
import com.tbl.modules.wms.constant.Constant;
import com.tbl.modules.wms.constant.EmumConstant;
import com.tbl.modules.wms.entity.allo.Allocation;
import com.tbl.modules.wms.entity.allo.AllocationDetail;
import com.tbl.modules.wms.service.allo.AllocationDetailService;
import com.tbl.modules.wms.service.allo.AllocationService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 调拨管理--出库管理
 * @author 70486
 */
@Controller
@RequestMapping(value = "/allostorageout")
public class AlloStorageOutController extends AbstractController {

    /**
     * 调拨管理-调拨表
     */
    @Autowired
    private AllocationService allocationService;
    /**
     * 调拨管理-调拨详情
     */
    @Autowired
    private AllocationDetailService allocationDetailService;

    /**
     * 跳转到调拨出库管理页面
     * @return ModelAndView
     */
    @RequestMapping("/storageList")
    public ModelAndView storageList() {
        ModelAndView mv = this.getModelAndView();
        mv.setViewName("techbloom/allo/allooutstorage/allooutstorage_list");
        return mv;
    }

    /**
     * 调拨出库列表页数据
     * @param queryJsonString 查询条件
     * @return Map<String , Object>
     */
    @RequestMapping(value = "/storageListData.do")
    @ResponseBody
    public Map<String, Object> storageListData(String queryJsonString) {
        Map<String, Object> map = new HashMap<>(5);
        if (!StringUtils.isEmptyString(queryJsonString)) {
            map = JSON.parseObject(queryJsonString);
        }
        map.put("state", EmumConstant.locationChangeStatus.START_CHANGE_OUT.getCode());
        PageTbl page = this.getPage();
        PageUtils utils = allocationService.getPageList(page, map);
        page.setTotalRows(utils.getTotalCount() == 0 ? 1 : utils.getTotalCount());
        //初始化分页对象
        executePageMap(map, page);
        map.put("rows", utils.getList());
        map.put("total", utils.getTotalPage() == 0 ? 1 : utils.getTotalPage());
        return map;
    }

    /**
     * 点击执行跳转到执行界面
     * @param id 调拨单主键
     * @return ModelAndView
     */
    @RequestMapping(value = "/execute.do")
    @ResponseBody
    public ModelAndView execute(Integer id) {
        ModelAndView mv = this.getModelAndView();
        mv.addObject("id", id);
        mv.setViewName("techbloom/allo/allooutstorage/allooutstorage_execute");
        return mv;
    }

    /**
     * 执行拣货操作列表
     * @param id 调拨单主键
     * @return Map<String,Object>
     */
    @RequestMapping(value = "/detailList.do")
    @ResponseBody
    public Map<String, Object> detailList(Integer id) {
        Map<String, Object> map = new HashMap<>(3);
        PageTbl page = this.getPage();
        PageUtils utils = allocationService.getPageDetailList(page, id);
        page.setTotalRows(utils.getTotalCount() == 0 ? 1 : utils.getTotalCount());
        //初始化分页对象
        executePageMap(map, page);
        map.put("rows", utils.getList());
        map.put("total", utils.getTotalPage() == 0 ? 1 : utils.getTotalPage());
        return map;
    }

    /**
     * 点击查看，跳转到列表页
     * @param id 调拨单主键
     * @return ModelAndView
     */
    @RequestMapping(value = "/toInfo.do")
    @ResponseBody
    public ModelAndView toInfo(Long id) {
        ModelAndView mv = this.getModelAndView();
        mv.addObject("infoId", id);
        mv.setViewName("techbloom/allo/allooutstorage/allooutstorage_info");
        return mv;
    }

    /**
     * 点击编辑，跳转到编辑页面
     * @param id 调拨单主键
     * @return ModelAndView
     */
    @RequestMapping(value = "/editInfo.do")
    @ResponseBody
    public ModelAndView editInfo(Long id) {
        ModelAndView mv = this.getModelAndView();
        mv.addObject("info", allocationService.selectById(id));
        mv.setViewName("techbloom/allo/allooutstorage/allooutstorage_edit");
        return mv;
    }

    /**
     * 点击编辑，点击保存  保存主表信息
     * @param allocation 调拨单
     * @return Map<String,Object>
     */
    @RequestMapping(value = "/saveOutStorage")
    @ResponseBody
    public Map<String, Object> saveOutStorage(Allocation allocation) {
        Map<String, Object> map = new HashMap<>(2);
        boolean result = allocationService.insertOrUpdate(allocation);
        map.put("result", result);
        map.put("msg", result?"保存成功！":"保存失败！");
        return map;
    }

    /**
     * 点击编辑，点击提交，修改状态
     * @param allocation 调拨单
     * @return Map<String,Object>
     */
    @RequestMapping(value = "/subOutStorage")
    @ResponseBody
    public Map<String, Object> subOutStorage(Allocation allocation) {
        Map<String, Object> map = Maps.newHashMap();
        allocation.setState(EmumConstant.locationChangeStatus.START_CHANGE_OUT.getCode());
        boolean result = allocationService.insertOrUpdate(allocation);
        map.put("result", result);
        map.put("msg", result?"提交成功！":"提交失败！");
        return map;
    }

    /**
     * 点击编辑，获取质保单号列表
     * @param pageSize 页面大小
     * @param pageNo 页码
     * @param id 调拨单主键
     * @return Map<String,Object>
     */
    @RequestMapping(value = "/getQaCode")
    @ResponseBody
    public Map<String, Object> getQaCode(int pageSize, int pageNo, Long id) {
        Map<String, Object> map = Maps.newHashMap();
        Allocation allocation = allocationService.selectById(id);
        if (allocation != null) {
            map.put("warehouseCode", allocation.getOutWarehouseCode());
            PageTbl page = this.getPage();
            page.setPagesize(pageSize);
            page.setPageno(pageNo);
            PageUtils utils = allocationService.getQaCode(page, map);
            map.put("result", utils.getList() == null ? "" : utils.getList());
            map.put("total", utils.getTotalPage() == 0 ? 1 : utils.getTotalPage());
        } else {
            map.put("result", "");
            map.put("total", 0);
        }
        return map;
    }

    /**
     * 点击编辑，发货单详情添加
     * @param id 调拨单主键
     * @param qaCodeIds 详情质保号
     * @param factoryCode 厂区编码
     * @return  Map<String, Object>
     */
    @RequestMapping(value = "/saveOutstorageDetail")
    @ResponseBody
    public Map<String, Object> saveOutstorageDetail(Long id, String[] qaCodeIds, String factoryCode) {
        Map<String, Object> map = Maps.newHashMap();
        boolean result = allocationService.saveAllocationDetail(id, qaCodeIds, factoryCode, getUserId());
        map.put("result", result);
        map.put("msg", result?"添加成功":"添加失败");
        return map;
    }

    /**
     * 点击编辑，删除详情数据
     * @param ids 调拨明细主键
     * @return Map<String,Object>
     */
    @RequestMapping(value = "/delOutstorageDetail")
    @ResponseBody
    public Map<String, Object> delDetail(String[] ids) {
        return allocationService.deleteAllocationDetailIds(ids);
    }

    /**
     * 点击出库执行，点击绑定行车  跳转行车绑定页面
     * @param detailId 调拨明细主键
     * @param infoId 调拨单主键
     * @return ModelAndView
     */
    @RequestMapping(value = "/carbind.do")
    @ResponseBody
    public ModelAndView carbind(Long detailId, Long infoId) {
        ModelAndView mv = this.getModelAndView();
        AllocationDetail allocationDetail = allocationDetailService.selectById(detailId);
        mv.setViewName("techbloom/allo/allooutstorage/allocar_bind");
        mv.addObject("detail", allocationDetail);
        mv.addObject("carList", allocationService.selectCarListByWarehouseCode(allocationDetail.getOutWarehouseCode(),
                //okk
                Arrays.asList(getSessionUser().getFactoryCode().split(","))));
        mv.addObject("infoId", infoId);
        return mv;
    }

    /**
     * 出库执行-绑定行车  点击保存行车信息
     * @param allocationDetail 调拨单明细
     * @return Map<String,Object> 成功失败结果集
     */
    @RequestMapping(value = "/saveCar")
    @ResponseBody
    public Map<String, Object> saveCar(AllocationDetail allocationDetail) {
        Map<String, Object> map = Maps.newHashMap();
        boolean result = allocationService.saveCar(allocationDetail);
        map.put("result", result);
        map.put("msg", result?"行车绑定成功！":"行车绑定失败！");
        return map;
    }

    /**
     * 点击出库执行，点击开始拣货
     * @param id 调拨表详情表主键
     * @return Map<String,Object>
     */
    @RequestMapping(value = "/detailStart")
    @ResponseBody
    public Map<String, Object> detailStart(Long id) {
        Map<String, Object> map = Maps.newHashMap();
        String msg;
        map.put("result", false);
        AllocationDetail allocationDetail = allocationDetailService.selectById(id);
        if (allocationDetail.getOutCarCode() == null) {
            msg = "请先绑定行车";
            map.put("msg", msg);
            return map;
        }
        if (allocationDetail.getState().equals(EmumConstant.locationChangeStatus.START_CHANGE_OUT.getCode())){
            msg = "已经开始调拨出库，请勿重新提交";
            map.put("msg", msg);
            return map;
        }
        if (allocationDetail.getState().equals(EmumConstant.locationChangeStatus.COMPLETE_CHANGE_OUT.getCode())) {
            msg = "已进完成调拨出库，请勿重复提交";
            map.put("msg", msg);
            return map;
        }
        if (allocationDetail.getState().equals(EmumConstant.locationChangeStatus.START_CHANGE_IN.getCode())) {
            msg = "已开始调拨入库操作，请勿重复提交";
            map.put("msg", msg);
            return map;
        }
        if (allocationDetail.getState().equals(EmumConstant.locationChangeStatus.COMPLETE_CHANGE_IN.getCode())) {
            msg = "已完成调拨入库操作，请勿重复提交";
            map.put("msg", msg);
            return map;
        }
        boolean result = allocationService.detailStart(id);
        map.put("result", result);
        map.put("msg", result?"更新成功！":"更新失败！");
        return map;
    }

    /**
     * 点击出库执行，点击拣货完成
     * @param id 调拨单明细主键
     * @return Map<String,Object>
     */
    @RequestMapping(value = "/detailSuccess")
    @ResponseBody
    public Map<String, Object> detailSuccess(Long id) {
        Map<String, Object> map = Maps.newHashMap();
        map.put("result", false);
        AllocationDetail allocationDetail = allocationDetailService.selectById(id);
        if (EmumConstant.locationChangeStatus.COMPLETE_CHANGE_OUT.getCode().equals(allocationDetail.getState())) {
            map.put("msg", "已进完成调拨出库，请勿重复提交");
            return map;
        }
        if (EmumConstant.locationChangeStatus.START_CHANGE_IN.getCode().equals(allocationDetail.getState())) {
            map.put("msg", "已开始调拨入库操作，请勿重复提交");
            return map;
        }
        if (EmumConstant.locationChangeStatus.COMPLETE_CHANGE_IN.getCode().equals(allocationDetail.getState())) {
            map.put("msg", "已完成调拨入库操作，请勿重复提交");
            return map;
        }
        boolean result = allocationService.detailSuccess(id, getUserId());
        map.put("result", result);
        map.put("msg", result?"更新成功！":"更新失败！");
        return map;
    }

    /**
     * 点击确认出库，把所有选中的调拨明细出掉
     * @param ids 调拨单明细主键数组
     * @return Map<String,Object>
     */
    @RequestMapping(value = "/allStorageOut")
    @ResponseBody
    public Map<String, Object> allStorageOut(String[] ids) {
        List<Long> lstRemove = new ArrayList<>();
        List<Long> lstIds = Arrays.stream(ids).map(s -> Long.parseLong(s.trim())).collect(Collectors.toList());
        List<AllocationDetail> lstAllocationDetail = allocationDetailService.selectBatchIds(lstIds);
        lstAllocationDetail.forEach(allocationDetail -> {
            if (allocationDetail.getState() == Constant.INT_THREE || allocationDetail.getState() == Constant.INT_FOUR
                    || allocationDetail.getState() == Constant.INT_FIVE) {
                lstRemove.add(allocationDetail.getId());
            }
        });

        //去掉已经完成出库的明细
        lstIds.removeAll(lstRemove);

        return allocationService.allStorageOut(lstIds, getUserId());
    }

    /**
     * 导出excel
     * @param request
     * @param response
     */
    @RequestMapping(value = "/toExcel.do")
    @ResponseBody
    public void toExcel(HttpServletRequest request, HttpServletResponse response) {
        Map<String, Object> map = new HashMap<>(4);
        map.put("ids", StringUtils.stringToInt(request.getParameter("ids")));
        map.put("allCode", request.getParameter("queryAllCode"));
        map.put("startTime", request.getParameter("queryStartTime"));
        map.put("endTime", request.getParameter("queryEndTime"));
        try {
            String sheetName = "调拨出库" + "(" + DateUtils.getDay() + ")";
            response.setHeader("Content-Type", "application/force-download");
            response.setHeader("Content-Type", "application/vnd.ms-excel");
            response.setCharacterEncoding("UTF-8");
            response.setHeader("Expires", "0");
            response.setHeader("Cache-Control", "must-revalidate, post-check=0, pre-check=0");
            response.setHeader("Pragma", "public");
            response.setHeader("Content-disposition", "attachment;filename=" + new String(sheetName.getBytes("gbk"),
                    "ISO8859-1") + ".xls");

            Map<String, String> mapFields = new LinkedHashMap<>();
            String [] excelIndexArray = request.getParameter("queryExportExcelIndex").split(",");

            if (excelIndexArray.length==1 && "".equals(excelIndexArray[0])) {
                mapFields.put("allCode", "调拨单号");
                mapFields.put("moveTimeStr", "创建时间");
                mapFields.put("factoryName", "调出厂区");
                mapFields.put("inFactoryName", "调入厂区");
                mapFields.put("userName", "创建人");
                mapFields.put("alloState", "单据状态");
            }else {
                for (String s : excelIndexArray) {
                    if ("2".equals(s)) {
                        mapFields.put("allCode", "调拨单号");
                    } else if ("3".equals(s)) {
                        mapFields.put("moveTimeStr", "创建时间");
                    } else if ("4".equals(s)) {
                        mapFields.put("factoryName", "调出厂区");
                    } else if ("5".equals(s)) {
                        mapFields.put("inFactoryName", "调入厂区");
                    } else if ("6".equals(s)) {
                        mapFields.put("userName", "创建人");
                    } else if ("7".equals(s)) {
                        mapFields.put("alloState", "单据状态");
                    }
                }
            }

            DeriveExcel.exportExcel(sheetName, allocationService.getAlloStorageOutExcel(map), mapFields, response, "");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 导出excel
     * @param request
     * @param response
     */
    @RequestMapping(value = "/detailExcel.do")
    @ResponseBody
    public void detailExcel(HttpServletRequest request, HttpServletResponse response) {
        Map<String, Object> map = new HashMap<>(2);
        map.put("ids", StringUtils.stringToInt(request.getParameter("ids")));
        map.put("id", request.getParameter("infoid"));
        try {
            String sheetName = "调拨出库详细" + "(" + DateUtils.getDay() + ")";
            response.setHeader("Content-Type", "application/force-download");
            response.setHeader("Content-Type", "application/vnd.ms-excel");
            response.setCharacterEncoding("UTF-8");
            response.setHeader("Expires", "0");
            response.setHeader("Cache-Control", "must-revalidate, post-check=0, pre-check=0");
            response.setHeader("Pragma", "public");
            response.setHeader("Content-disposition", "attachment;filename=" + new String(sheetName.getBytes("gbk"),
                    "ISO8859-1") + ".xls");

            Map<String, String> mapFields = new LinkedHashMap<>();
            mapFields.put("qaCode", "质保单号");
            mapFields.put("batchNo", "批次号");
            mapFields.put("materialCode", "物料编码");
            mapFields.put("materialName", "物料名称");
            mapFields.put("meter", "米数");
            mapFields.put("outStorageTimeStr", "完成出库时间");
            mapFields.put("pickManName", "拣货人");
            mapFields.put("stateStr", "状态 ");

            mapFields.put("allCode", "调拨单号");
            mapFields.put("movetime", "创建时间");
            mapFields.put("factoryName", "调出厂区");
            mapFields.put("inFactoryName", "调入厂区");
            mapFields.put("outWarehouseName", "创建人");

            DeriveExcel.exportExcel(sheetName, allocationDetailService.getAlloStorageOutDetailExcel(map), mapFields, response, "");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }



}
